﻿using System;
using System.Linq;
using RanchBuddy.Core.Domain;
using RanchBuddy.Core.Domain.Impl;
using RanchBuddy.Core.Services.Impl;
using StructureMap;

namespace RanchBuddy.Core.DataAccess.Impl
{
    [Pluggable("Default")]
    public class AccountRepository : IAccountRepository
    {
        public IAccount GetAccountByEmail(string Email)
        {
            IAccount result = null;
            using (RanchBuddyDataContext dc = ObjectFactory.GetInstance<IConnection>().GetLsContext())
            {
                result = dc.Accounts.Where(a => a.Email == Email).FirstOrDefault();
            }
            return result;
        }

        public IAccount GetAccountByUsername(string Username)
        {
            IAccount result = null;
            using (RanchBuddyDataContext dc = ObjectFactory.GetInstance<IConnection>().GetLsContext())
            {
                result = dc.Accounts.Where(a => a.Username == Username).FirstOrDefault();
            }
            return result;
        }

        /// <summary>
        /// Checks to see if this email is in use or not
        /// </summary>
        /// <param name="account"></param>
        /// <returns>true = exists, false = doesn't exist</returns>
        public bool EmailExists(string email)
        {
            bool result = true;
            using (RanchBuddyDataContext dc = ObjectFactory.GetInstance<IConnection>().GetLsContext())
            {
                if (dc.Accounts.Where(a => a.Email == email).FirstOrDefault() == null)
                    result = false;
            }
            return result;
        }

        /// <summary>
        /// Checks to see if this username is in use or not
        /// </summary>
        /// <param name="account"></param>
        /// <returns>true = exists, false = doesn't exist</returns>
        public bool UsernameExists(string username)
        {
            bool result = true;
            using (RanchBuddyDataContext dc = ObjectFactory.GetInstance<IConnection>().GetLsContext())
            {
                if (dc.Accounts.Where(a => a.Username == username).FirstOrDefault() == null)
                    result = false;
            }
            return result;
        }

        public bool KeyExists(Guid VerificationKey)
        {
            bool result = false;

            using (RanchBuddyDataContext dc = ObjectFactory.GetInstance<IConnection>().GetLsContext())
            {
                IAccount account = null;
                try
                {
                    account = dc.Accounts.Where(a => (Guid) a.VerificationKey == VerificationKey).FirstOrDefault();
                }
                catch
                {
                    result = false;
                }

                if (account != null)
                {
                    account.EmailVerified = true;
                    dc.SubmitChanges();
                    result = true;
                }
            }
            return result;
        }

        /// <summary>
        /// Saves an account
        /// </summary>
        /// <param name="account"></param>
        /// <returns>RepositoryStatus with the results of the operation</returns>
        public IRepositoryStatus SaveAccount(IAccount account)
        {
            IRepositoryStatus rs = ObjectFactory.GetInstance<IRepositoryStatus>();
            try
            {
                account.Validate();

                using (RanchBuddyDataContext dc = ObjectFactory.GetInstance<IConnection>().GetLsContext())
                {
                    if(account.AccountID > 0)
                    {
                        IAccount original = dc.Accounts.Where(a => a.AccountID == account.AccountID).FirstOrDefault();
                    }
                    else
                    {
                        dc.Accounts.InsertOnSubmit(account as Account);
                    }
                    dc.SubmitChanges();
                }
                rs.SetObject(account);
                rs.AddMessage(HelpMessageService.GetHelpMessageBodyByID(15));
                rs.StatusType = Status.StatusTypes.Success;
            }
            catch(ValidationException ve)
            {
                rs.SetObject(account);
                rs.AddRuleViolations(account.GetRuleViolations().ToList());
                rs.StatusType = Status.StatusTypes.Failure;
            }
            catch(Exception e)
            {
                rs.SetObject(account);
                rs.AddMessage(e.Message + e.StackTrace);
                rs.StatusType = Status.StatusTypes.Failure;
                LoggingService.WriteLog("AccountController", "Register","Saving accunt failed", LoggingType.Error,e);
            }
            return rs;
        }

        /// <summary>
        /// Deletes an account
        /// </summary>
        /// <param name="account"></param>
        /// <returns>RepositoryStatus with the results of the operation</returns>
        public IRepositoryStatus DeleteAccount(IAccount account)
        {
            IRepositoryStatus rs = ObjectFactory.GetInstance<IRepositoryStatus>();
            try
            {
                using (RanchBuddyDataContext dc = ObjectFactory.GetInstance<IConnection>().GetLsContext())
                {
                    dc.Accounts.Attach(account as Account, true);
                    dc.Accounts.DeleteOnSubmit(account as Account);
                    dc.SubmitChanges();
                }
                rs.SetObject(new object());
                rs.AddMessage(HelpMessageService.GetHelpMessageBodyByID(16));
                rs.StatusType = Status.StatusTypes.Success;
            }
            catch(Exception e)
            {
                rs.SetObject(new object());
                rs.AddMessage(e.Message + e.StackTrace);
                rs.StatusType = Status.StatusTypes.Failure;
            }
            return rs;
        }
    }
}